import {getBrowserFlag} from "./function/CommonUtils";
import {AjaxType, YozoApiMethod} from "./constant/WebOfficeCons";
import {Dictionary} from "./types/Types";
import jq=require("jquery");

export class WebofficeProxyPlugin {
    mobileFlag:boolean = !!navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
    opened:boolean;
    appFrameContentWindow:any;

    public getYozoApplication(){
        if(this.opened&&this.appFrameContentWindow!==undefined)
            return this.appFrameContentWindow.YozoOffice.Application;
    }
    public requestServer(ajaxOpts:JQuery.AjaxSettings){
        return jq.ajax(ajaxOpts);
    }

    public openFile(ajaxOpts:JQuery.AjaxSettings):JQuery.Promise<any,any,any>{
        let defer=jq.Deferred();
        jq.ajax(ajaxOpts).then((result:any)=>{
            if (result) {
                if (result.errorCode === "0") {
                    let rst:Dictionary<any> = result.result;
                    if (rst && rst.urls) {
                        this.openUrls(rst.urls).then(result=>{
                            this.getYozoApplication().ActiveDocument.TrackRevisions=true;
                            defer.resolve({errorCode:'0',errorMessage:"无错误",result:true});
                        },defer.reject);
                    } else {
                        console.warn("ajax响应内容data.result有问题：" + rst);
                        defer.reject({errorCode:'-1',errorMessage:"ajax响应内容data.result有问题"});
                    }
                }
            } else {
                console.warn("ajax响应内容为空!");
                defer.reject({errorCode:'-1',errorMessage:"ajax响应内容为空"});
            }
        },(hxr:JQuery.Promise<any,any,any>,statusText:string,error:string)=>{defer.reject({errorCode:'-1',errorMessage:error});});
        return defer.promise();
    }

    private openUrls(urls:string|string[]):JQuery.Promise<any,any,any> {
        let defer=jq.Deferred();
        if (jq.isArray(urls)) {
            if (this.mobileFlag || getBrowserFlag() === 3) {
                this.openUrl(urls[0]).then(defer.resolve,defer.reject);
            } else {
                (<string[]>urls).forEach(function (url) {
                    this.openUrl(url).then(defer.resolve,defer.reject);
                });
            }
        } else if (jq.type(urls) === "string") {
            this.openUrl(<string>urls).then(defer.resolve,defer.reject);
        } else {
            console.error("urls格式错误：");
            console.error(urls);
            defer.reject({errorCode:'-1',errorMessage:"urls格式错误"});
        }
        return defer.promise();
    }
    private openUrl(url:string) {
        return jq.Deferred(defer=>{
            if(this.appFrameContentWindow===undefined) {
                let iframe = jq("<iframe></iframe>").attr("width", "100%").attr("height", "100%").attr("allowfullscreen", "true")
                    .attr("id", "appFrame").attr("frameborder","0").attr("src", url).appendTo("body");
                this.appFrameContentWindow = (<HTMLIFrameElement>iframe[0]).contentWindow;
                iframe.on("load",()=>{
                    let intervalC=setInterval(()=>{
                        if(this.appFrameContentWindow.YozoOffice.Application){
                            this.opened=true;
                            defer.resolve({errorCode:'0',errorMessage:"无错误"});
                        }
                    },200);
                });
            }
            this.appFrameContentWindow.location.href=url;
        }).promise();
    }

    public deleteFile(ajaxOpts:JQuery.AjaxSettings):JQuery.Promise<any,any,any>{
        let defer=jq.Deferred();
        let getParentPathParams:JQuery.AjaxSettings;
        getParentPathParams={url:ajaxOpts.url,type:AjaxType.GET,
            data:{"jsonParams":encodeURIComponent(JSON.stringify({'method':YozoApiMethod.GETPARENTPATH}))}};
        jq.ajax(getParentPathParams).then((result:any)=>{
            if (result.errorCode === "0") {
                let parentPath:string = result.result;
                let params:JQuery.PlainObject=<JQuery.PlainObject>ajaxOpts.data;
                if(!params.filePath.startsWith(parentPath))
                    params.filePath=parentPath+params.filePath;
                let data:Dictionary<any>={'method':YozoApiMethod.DELETEDOC,'params':encodeURIComponent(JSON.stringify(params))};
                ajaxOpts.data=data;
                jq.ajax(ajaxOpts).then(defer.resolve, (error)=>{
                    defer.reject({errorCode:'-1',errorMessage:'删除文件出错！',result:error});
                });
            }else {
                defer.reject(result);
            }
        },(error)=>{
            defer.reject({errorCode:'-1',errorMessage:'删除文件出错！',result:error});
        });
        return defer.promise();
    }

    public uploadFile(ajaxOpts:JQuery.AjaxSettings):JQuery.Promise<any,any,any>{
        let self=this;
        let defer=jq.Deferred();
        try {
            let params: JQuery.PlainObject = <JQuery.PlainObject>ajaxOpts.data;
            let uploadform = jq("<form></form>").attr("id", "f");
            uploadform.appendTo('body');
            uploadform.empty();
            let uploadInput = jq("<input>").attr("name", "file").attr("type", "file").attr("style", "display:none;");
            uploadform.append(uploadInput);
            uploadform.append(jq("<input>").attr("type", "hidden").attr("name", "filePath").attr("value", params.filePath));
            uploadInput.trigger("click");
            uploadInput.on({
                change: (e: any) => {
                    self.doUploadFile(uploadform, ajaxOpts).then(defer.resolve, (error)=>{
                        defer.reject({errorCode:'-1',errorMessage:'上传文件出错！',result:error});
                    });
                }
            });
        }catch (e) {
            defer.reject({errorCode:'-1',errorMessage:e.message,result:false});
        }
        return defer.promise();
    }

    private doUploadFile(uploadform:any,ajaxOpts:JQuery.AjaxSettings) {
        let form = uploadform[0],
            formData:FormData = new FormData(form);
        ajaxOpts.data=formData;
        ajaxOpts.processData=false;
        ajaxOpts.contentType=false;
        return jq.ajax(ajaxOpts);
    }

    public execCommand(command:string):JQuery.Promise<any,any,any>{
        let me=this;
        return jq.Deferred(defer=>{
            try {
                if(!me.opened||me.appFrameContentWindow===undefined||me.appFrameContentWindow.YozoOffice===undefined) {
                    defer.reject({errorCode:'-1',errorMessage:'没有打开的文档或者文档未准备好！',result:false});
                    return;
                }
                let _command=command.replace(/[\s\?]*/g, "");
                if(_command.indexOf("function")===-1||_command.indexOf("function")>0)
                    command="function(){ return " + command + "}";
                let executor = me.appFrameContentWindow.eval("(0," + command + ")"),
                    result = executor();
                defer.resolve({errorCode: '0', errorMessage: "", result: result});
            }catch (e) {
                defer.reject({errorCode:'-1',errorMessage:e.message,result:false});
            }
        }).promise();
    }

    public acceptAllRevisions():JQuery.Promise<any,any,any>{
        let me=this;
        return jq.Deferred(defer=>{
            let application=me.getYozoApplication();
            if(application===undefined){
                defer.reject({errorCode:'-1',errorMessage:"无法获取到weboffice应用对象",result:false});
                return;
            }
            application.ActiveDocument.AcceptAllRevisions();
            defer.resolve({errorCode:'0',errorMessage:"",result:true});
        }).promise();

    }

    public addBookmark(name:string):JQuery.Promise<any,any,any>{
        let me=this;
        return jq.Deferred(defer=>{
                let realName:string=name.replace(/_/g,'|'),
                    application=me.getYozoApplication();
                if(application===undefined){
                    defer.reject({errorCode:'-1',errorMessage:"无法获取到weboffice应用对象",result:false});
                    return;
                }
                if(application.ActiveDocument.Bookmarks.Exists(name)||application.ActiveDocument.Bookmarks.Exists(realName)){
                    defer.reject({errorCode:'-1',errorMessage:"书签【"+name+"】已经存在",result:false});
                    return;
                }
                application.ActiveDocument.Bookmarks.Add(realName);
                defer.resolve({errorCode:'0',errorMessage:"",result:true});
            }).promise();
    }
    public deleteBookmark(name:string):JQuery.Promise<any,any,any>{
        let me=this;
        return jq.Deferred(defer=>{
            let application=me.getYozoApplication();
            if(application===undefined){
                defer.reject({errorCode:'-1',errorMessage:"无法获取到weboffice应用对象",result:false});
                return;
            }
            try{
                me.getBookmark(name).Delete();
                defer.resolve({errorCode:'0',errorMessage:"",result:true});
            }catch (e) {
                defer.reject({errorCode:'-1',errorMessage:e.message,result:false});
            }
        }).promise();
    }

    public getBookmarkValue(name:string):JQuery.Promise<any,any,any>{
        let me=this;
        return jq.Deferred(defer=>{
            let application=me.getYozoApplication();
            if(application===undefined){
                defer.reject({errorCode:'-1',errorMessage:"无法获取到weboffice应用对象",result:false});
                return;
            }
            try{
                let bookmark=me.getBookmark(name);
                let value:string=bookmark.Range.Text.replace(/\x0A/g,"");
                application.ActiveDocument.Range(0,0).Select();
                defer.resolve({errorCode:'0',errorMessage:"",result:value});
            }catch (e) {
                defer.reject({errorCode:'-1',errorMessage:e.message,result:false});
            }
        }).promise();
    }

    public getAllBookmarkValue():JQuery.Promise<any,any,any>{
        let me=this;
        return jq.Deferred(defer=>{
            let application=me.getYozoApplication();
            if(application===undefined){
                defer.reject({errorCode:'-1',errorMessage:"无法获取到weboffice应用对象",result:false});
                return;
            }
            try{
                let result:Array<any>=[],
                    bookmarks=application.ActiveDocument.Bookmarks,
                    count:number=bookmarks.Count;
                for(let i=1;i<=count;i++){
                    let bookmark=bookmarks.Item(i);
                    let text:string=bookmark.Range.Text.replace(/\x0A/g,"");
                    let realName:string=bookmark.Name;
                    realName=realName.replace(/\|/g,'_');
                    result.push({"name":realName,"value":text});
                }
                application.ActiveDocument.Range(0,0).Select();
                defer.resolve({errorCode:'0',errorMessage:"",result:result});
            }catch (e) {
                defer.reject({errorCode:'-1',errorMessage:e.message,result:false});
            }
        }).promise();
    }

    public setBookmarkValue(name:string,value:string):JQuery.Promise<any,any,any>{
        let me=this;
        return jq.Deferred(defer=>{
            let application=me.getYozoApplication();
            if(application===undefined){
                defer.reject({errorCode:'-1',errorMessage:"无法获取到weboffice应用对象",result:false});
                return;
            }
            try{
                let bookmark=me.getBookmark(name);
                if(!bookmark)
                    defer.reject({errorCode:'-1',errorMessage:"书签“"+name+"”不存在!",result:false});
                const bookmarkName=bookmark.Name,start=bookmark.Range.Start;
                bookmark.Select();
                application.Selection.Text=value+" ";
                application.ActiveDocument.Range(start,start+value.length+1).Select();
                this.addBookmark(bookmarkName).then(defer.resolve,defer.reject);
                // defer.resolve({errorCode:'0',errorMessage:"",result:value});
            }catch (e) {
                defer.reject({errorCode:'-1',errorMessage:e.message,result:false});
            }
        }).promise();
    }

    public locateBookmark(name:string):JQuery.Promise<any,any,any>{
        let me=this;
        return  jq.Deferred(defer=>{
            let application=me.getYozoApplication();
            if(application===undefined){
                defer.reject({errorCode:'-1',errorMessage:"无法获取到weboffice应用对象",result:false});
                return;
            }
            try{
                let bookmark=me.getBookmark(name);
                bookmark.Select();
                defer.resolve({errorCode:'0',errorMessage:"",result:true});
            }catch (e) {
                defer.reject({errorCode:'-1',errorMessage:e.message,result:false});
            }
        }).promise();
    }

    public getBookmark(name:string){
        let realName:string=name.replace(/_/g,'|');
        let application=this.getYozoApplication();
        if(application===undefined){
            throw new Error("无法获取到weboffice应用对象");
        }
        if(!application.ActiveDocument.Bookmarks.Exists(name)&&!application.ActiveDocument.Bookmarks.Exists(realName)){
            throw new Error("书签【"+name+"】不存在");
        }
        return application.ActiveDocument.Bookmarks.Item(name)||application.ActiveDocument.Bookmarks.Item(realName);
    }

}